package com.project.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.solon.plugins.pagination.Page;
import com.baomidou.mybatisplus.solon.service.impl.ServiceImpl;
import com.common.exception.ErrCode;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.project.business.entity.DeptEntity;
import com.project.business.entity.UserEntity;
import com.project.business.mapper.UserEntityMapper;
import com.project.business.service.DeptEntityService;
import com.project.business.service.UserEntityService;
import com.project.core.jwt.AuditAware;
import com.project.core.jwt.JwtUtil;
import org.eclipse.jetty.util.security.Credential;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;

import java.util.List;

@Component
public class UserEntityServiceImpl extends ServiceImpl<UserEntityMapper, UserEntity>
        implements UserEntityService {

    @Inject
    private DeptEntityService deptService;

    @Override
    public void edit(UserEntity entity) {
        // ...
    }

    @Override
    public UserEntity getOneById(Integer id) {
        ErrCode.Request_Param.nonNull(id, "用户id不能为空！");
        UserEntity user = this.getById(id);
        ErrCode.Request_Param.nonNull(user, "用户不存在！");
        DeptEntity dept = deptService.getById(user.getDeptId());
        user.setDeptName(dept == null ? "" : dept.getName());
        return user;
    }

    @Override
    public void add(UserEntity entity) {
        // ...
    }

    @Override
    public void logout() {
        // TODO 删除redis数据，暂时没做
    }

    @Override
    public String login(String username, String password) {
        ErrCode.Request_Param.nonNull(username, "账户或密码不能为空！");
        ErrCode.Request_Param.nonNull(password, "账户或密码不能为空！");
        UserEntity userEntity = this.getOneByUsername(username, password);
        ErrCode.Request_Param.nonNull(userEntity, "账户或密码错误！");
        AuditAware.init(userEntity.getId());
        // -1 永不过期
        return JwtUtil.generateToken(userEntity.getId(), -1);
        // TODO 生成token后保存到redis，暂不处理
    }

    @Override
    public List<UserEntity> lists() {
        return this.baseMapper.selectJoinList(UserEntity.class,
                new MPJLambdaWrapper<UserEntity>()
                        // 获取user属性
                        // selectAll 获取全部
                        .selectAll(UserEntity.class)
                        // 获取特定字段
                        //  .select(UserEntity::getId, UserEntity::getDeptId, UserEntity::getName, UserEntity::getPhone, UserEntity::getRealName)
                        // 这里的意思是 从 dept 里面获取到 name 作为user对象中的 deptName的值
                        .selectAs(DeptEntity::getName, UserEntity::getDeptName)
                        // 左连接 dept，后面是两个条件
                        .leftJoin(DeptEntity.class, DeptEntity::getId, UserEntity::getDeptId)
        );
    }

    @Override
    public IPage<UserEntity> pages(Integer page, Integer size) {
        // 和上面唯一的区别就是 增加了个 new Page<>(page, size)
        return this.baseMapper.selectJoinPage(new Page<>(page, size), UserEntity.class,
                new MPJLambdaWrapper<UserEntity>()
                        // 获取user属性
                        // selectAll 获取全部
                        .selectAll(UserEntity.class)
                        // 获取特定字段
                        // .select(UserEntity::getId, UserEntity::getDeptId, UserEntity::getName, UserEntity::getPhone, UserEntity::getRealName)
                        // 这里的意思是 从 dept 里面获取到 name 作为user对象中的 deptName的值
                        .selectAs(DeptEntity::getName, UserEntity::getDeptName)
                        // 左连接 dept，后面是两个条件
                        .leftJoin(DeptEntity.class, DeptEntity::getId, UserEntity::getDeptId)
        );
    }

    private UserEntity getOneByUsername(String username, String password) {
        QueryWrapper<UserEntity> query = new QueryWrapper<>();
        String newPass = Credential.MD5.digest(password).toUpperCase().replaceFirst("MD5:", "");
        query.lambda().eq(UserEntity::getPassword, newPass)
                .and(q -> q.eq(UserEntity::getName, username).or().eq(UserEntity::getPhone, username));
        return this.getOne(query);
    }
}




